
#include <BReadWrite>
#include "IHtmlStyle.h"
#include "member_BWidget.h"
#include "member_BObject.h"
#include "member_BHtmlItem.h"

using namespace BWE;

IHtmlStyle::IHtmlStyle()
{
	parent = 0;
}
IHtmlStyle::IHtmlStyle(const BString& name) : BObject(name)
{
	parent = 0;
}
IHtmlStyle::~IHtmlStyle()
{

}

bool IHtmlStyle::apply(BHtmlItem* item) const
{
	const BString& itemName = item->name();
	const BString& itemId = item->attrib("id");
	const BStringArray& classes = item_member(item)->classes;
	bool changed = false;
	for (int i = 0; i < children.size(); i++)
	{
		IHtmlStyle* child = children[i];
		const BString& name = child->name();
		if (name.size() && name != itemName)
			continue;
		if (child->id.size() && child->id != itemId)
			continue;
		if (child->cls.size() && !classes.contain(child->cls))
			continue;
		if (!item_member(item)->realStyle)
		{
			item_member(item)->realStyle = new IHtmlStyle();
		}
		IHtmlStyle* realStyle = item_member(item)->realStyle;
		realStyle->overlap(child);
		changed = true;
	}
	return changed;
}
void IHtmlStyle::overlap(const IHtmlStyle* style)
{
	if (style == this)
		return;
	if (style == 0)
		return;
	if (style->valueMap.size())
	{
		for (auto it = style->valueMap.begin(); it.valid(); it++)
		{
			valueMap[it.key()] = it.value();
		}
	}
	if (style->children.size())
	{
		for (int i = 0; i < style->children.size(); i++)
		{
			IHtmlStyle* child = style->children[i];
			if (children.lower(child))
				continue;
			children.append(child);
		}
	}
}

void IHtmlStyle::setValue(const BString& name, const BValue& value)
{
	if (name.empty())
		return;
	valueMap[name] = value;
}
bool IHtmlStyle::removeVlaue(const BString& name)
{
	return valueMap.remove(name);
}
const BValue& IHtmlStyle::value(const BString& name) const
{
	if (name.size())
	{
		auto it = valueMap.find(name);
		if (it.valid())
			return *it;
	}
	return valueMap.def();
}

bool IHtmlStyle::clearValues()
{
	if (valueMap.empty())
		return false;
	valueMap.clear();
	return true;
}

bool IHtmlStyle::addSub(IHtmlStyle* style)
{
	if (!style)
		return false;
	annexes.append(style);
	return true;
}
bool IHtmlStyle::removeSub(IHtmlStyle* style)
{
	if (annexes.remove(style))
	{
		return true;
	}
	return false;
}
bool IHtmlStyle::clearSubs()
{
	annexes.clear();
	return true;
}

int IHtmlStyle::annexCount() const
{
	return annexes.size();
}
IHtmlStyle* IHtmlStyle::annex(int index)
{
	return annexes(index);
}
const IHtmlStyle* IHtmlStyle::annex(int index) const
{
	return annexes(index);
}
IHtmlStyle* IHtmlStyle::annex(const BString& name)
{
	for (int i = 0; i < annexes.size(); i++)
	{
		IHtmlStyle* annex = annexes[i];
		if (annex->name() != name)
			continue;
		return annex;
	}
	return 0;
}
const IHtmlStyle* IHtmlStyle::annex(const BString& name) const
{
	for (int i = 0; i < annexes.size(); i++)
	{
		IHtmlStyle* annex = annexes[i];
		if (annex->name() != name)
			continue;
		return annex;
	}
	return 0;
}
IHtmlStyle* IHtmlStyle::annex(const char* name)
{
	for (int i = 0; i < annexes.size(); i++)
	{
		IHtmlStyle* annex = annexes[i];
		if (annex->name() != name)
			continue;
		return annex;
	}
	return 0;
}
const IHtmlStyle* IHtmlStyle::annex(const char* name) const
{
	for (int i = 0; i < annexes.size(); i++)
	{
		IHtmlStyle* annex = annexes[i];
		if (annex->name() != name)
			continue;
		return annex;
	}
	return 0;
}

bool IHtmlStyle::addChild(IHtmlStyle* child)
{
	if (!child)
		return false;
	if (child && this != child && !children.contain(child))
	{
		BHolder<IHtmlStyle> holder(child);
		if (child->parent)
		{
			child->parent->removeChild(child);
		}
		child->parent = this;
		children.append(child);
		return true;
	}
	return false;
}
IHtmlStyle* IHtmlStyle::addChild(const BString& name)
{
	IHtmlStyle* style = new IHtmlStyle(name);
	this->addChild(style);
	return style;
}
bool IHtmlStyle::removeChild(IHtmlStyle* child)
{
	if (children.contain(child))
	{
		child->parent = 0;
		children.remove(child);
		return true;
	}
	return false;
}
bool IHtmlStyle::clearChildren()
{
	while (IHtmlStyle* child = children.first())
	{
		child->parent = 0;
		children.remove(0);
	}
	return true;
}

int IHtmlStyle::childCount() const
{
	return children.size();
}
IHtmlStyle* IHtmlStyle::child(int index)
{
	return children(index);
}
const IHtmlStyle* IHtmlStyle::child(int index) const
{
	return children(index);
}

IHtmlStyle* IHtmlStyle::child(const BString& name)
{
	for (int i = 0; i < children.size(); i++)
	{
		IHtmlStyle* child = children[i];
		if (child->name() != name)
			continue;
		return child;
	}
	return 0;
}
const IHtmlStyle* IHtmlStyle::child(const BString& name) const
{
	for (int i = 0; i < children.size(); i++)
	{
		IHtmlStyle* child = children[i];
		if (child->name() != name)
			continue;
		return child;
	}
	return 0;
}

IHtmlStyle* IHtmlStyle::child(const BString& name, const BString& id, const BString& cls)
{
	for (int i = 0; i < children.size(); i++)
	{
		IHtmlStyle* child = children[i];
		if (child->name() != name)
			continue;
		if (child->id != id)
			continue;
		if (child->cls != cls)
			continue;
		return child;
	}
	return 0;
}

